/**  
 * @author renbangjie renbangjie@126.com  
 * @date 2015-10-9 上午9:09:12
 * @version V1.0  
 * <b>Copyright (c)</b> 2014医信金融信息服务（上海）有限公司-版权所有<br/>
 */
package com.yjd.comm.pay.util;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.log4j.Logger;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yjd.comm.pay.dto.RechargeOrderDto;
import com.yjd.comm.pay.enums.RechChannel;
import com.yjd.comm.pay.model.QuickPayOrder;
import com.yjd.comm.recharge.model.OrderModel;
import com.yjd.comm.system.util.SysParamUtil;
import com.yjd.comm.util.CryptAES;
import com.yjd.comm.util.FrameUtil;
import com.yjd.comm.util.SecurityCode;
import com.yjd.comm.vo.Constant.SysParamKeyEnum;

/**
 * 快捷支付-工具类
 * 
 * @author renbangjie renbangjie@126.com
 * @date 2015-10-9 上午9:09:12
 */
public class QuickPayUtils {

	private final static Logger logger = Logger.getLogger(QuickPayUtils.class);

	/**
	 * 生成订单
	 * 
	 * @param rechargeOrder
	 * @param dbOrder
	 * @return QuickPayOrder
	 * @throws Exception
	 */
	public static QuickPayOrder generateOrder(RechargeOrderDto rechargeOrder,
			OrderModel dbOrder) throws Exception {

		if (rechargeOrder == null || dbOrder == null) {
			FrameUtil.throwBaseException1("参数异常");
		}

		QuickPayOrder quick = QuickPayUtils.getInstance(rechargeOrder);

		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("pay_order", dbOrder.getOrder_id().toString());
		paramMap.put("pay_title", rechargeOrder.getMemo());
		paramMap.put("pay_money", dbOrder.getPrice().toString());
		paramMap.put("bank_code", dbOrder.getBankcode());
		paramMap.put("bank_card_no", rechargeOrder.getBankCardNo());
		paramMap.put("bank_card_idname", rechargeOrder.getRealName());
		paramMap.put("bank_card_idcard", rechargeOrder.getCertNo());
		paramMap.put("mpNumber", rechargeOrder.getMpNumber());
		paramMap.put("pay_url_return", quick.getReturnUrl());
		paramMap.put("pay_url_notice", quick.getCallBackUrl());
		paramMap.put("user_id", dbOrder.getUser_id().toString());
		paramMap.put("rech_type", rechargeOrder.getRechType());
		paramMap.put("parameter",
				dbOrder.getUser_id() + "," + rechargeOrder.getUsername() + ","
						+ rechargeOrder.getRegDate());

		String appMsg = JSONUtils.toJSONString(paramMap);
		if (StringUtils.isBlank(appMsg)) {
			FrameUtil.throwBaseException1("数据异常");
		}

		quick.setAppMsg(
				CryptAES.AES_Encrypt(SecurityCode.md5(quick.getKey()), appMsg));

		return quick;

	}

	/**
	 * 解析回调参数
	 * 
	 * @param appMsg
	 * @return QuickPayOrder
	 */
	public static QuickPayOrder parseOrder(Map<String, Object> resultMap) {
		if (resultMap == null) {
			FrameUtil.throwBaseException1("参数异常");
		}
		String sysOrderId = (String) resultMap.get("sysOrderId");
		String finishTime = (String) resultMap.get("finishTime");
		if (StringUtils.isBlank(sysOrderId) || !NumberUtils.isNumber(sysOrderId)
				|| StringUtils.isBlank(finishTime)
				|| !NumberUtils.isNumber(finishTime)) {
			FrameUtil.throwBaseException1("参数异常");
		}

		QuickPayOrder quickOrder = new QuickPayOrder();
		quickOrder.setTransId((String) resultMap.get("transId"));
		quickOrder.setSysOrderId(sysOrderId);
		quickOrder.setStatus((String) resultMap.get("status"));
		quickOrder.setResultMsg((String) resultMap.get("resultMsg"));
		quickOrder.setFinishTime(finishTime);
		quickOrder.setDesc((String) resultMap.get("desc"));
		quickOrder.setOrderAmount((String) resultMap.get("orderAmount"));
		quickOrder.setBankCode((String) resultMap.get("bankCode"));
		quickOrder.setBankCardNo((String) resultMap.get("bankCardNo"));
		quickOrder.setCertNo((String) resultMap.get("certNo"));
		quickOrder.setRealName((String) resultMap.get("realName"));
		quickOrder.setMemo((String) resultMap.get("memo"));
		quickOrder.setMpNumber((String) resultMap.get("mpNumber"));
		quickOrder.setUser_id((String) resultMap.get("user_id"));
		quickOrder.setRechType((String) resultMap.get("rech_type"));

		return quickOrder;
	}

	/**
	 * 解析参数
	 * 
	 * @param appMsg
	 * @return Map<String,Object>
	 * @throws Exception
	 */
	public static Map<String, Object> resultMap(String appMsg, String app_user)
			throws Exception {

		if (StringUtils.isBlank(appMsg)) {
			FrameUtil.throwBaseException1("参数异常");
		}

		String message = CryptAES
				.AES_Decrypt(SecurityCode.md5(getKey(app_user)), appMsg);
		logger.info("=========================App接口返回信息:" + appMsg);
		if (StringUtils.isBlank(message)) {
			FrameUtil.throwBaseException1("无法解析的请求");
		}

		JSONObject resultMsg = JSONObject.parseObject(message);
		if (resultMsg == null) {
			FrameUtil.throwBaseException1("参数有误");
		}
		JSONObject statusMap = resultMsg.getJSONObject("AppResult");
		JSONObject backMap = resultMsg.getJSONObject("PayBack");
		JSONObject paramMap = resultMsg.getJSONObject("RequestParms");
		if (statusMap == null || paramMap == null || backMap == null) {
			FrameUtil.throwBaseException1("参数有误");
		}

		Map<String, Object> resultMap = new HashMap<String, Object>();

		resultMap.put("resultMsg", statusMap.getString("Msg"));

		resultMap.put("transId", backMap.getString("pay_trace"));
		resultMap.put("status", backMap.getString("pay_code"));
		resultMap.put("finishTime", backMap.getString("finish_time"));
		resultMap.put("orderAmount", backMap.getString("pay_money"));
		resultMap.put("bankCode", backMap.getString("bank_code"));

		resultMap.put("sysOrderId", paramMap.getString("pay_order"));
		resultMap.put("desc", paramMap.getString("pay_title"));
		resultMap.put("bankCardNo", paramMap.getString("bank_card_no"));
		resultMap.put("realName", paramMap.getString("bank_card_idname"));
		resultMap.put("certNo", paramMap.getString("bank_card_idcard"));
		resultMap.put("mpNumber", paramMap.getString("mpNumber"));
		resultMap.put("user_id", paramMap.getString("user_id"));
		resultMap.put("rech_type", paramMap.getString("rech_type"));

		return resultMap;

	}

	/**
	 * 校验
	 * 
	 * @param paramMap
	 * @return boolean
	 */
	public static boolean authentication(Map<String, Object> paramMap) {
		QuickPayOrder quickOrder = parseOrder(paramMap);
		if (quickOrder == null || StringUtils.isBlank(quickOrder.getStatus())
				|| !"100".equals(quickOrder.getStatus())) {
			return false;
		}
		return true;
	}

	/**
	 * 获取接口配置信息
	 * 
	 * @return BaoFooOrder
	 * @throws Exception
	 */
	public static QuickPayOrder getInstance(RechargeOrderDto rechargeOrder)
			throws Exception {

		if (rechargeOrder == null) {
			FrameUtil.throwBaseException1("参数异常");
		}
		// 充值参数
		String rech_conf = SysParamUtil
				.getValue(SysParamKeyEnum.PC_APP_RECH_CONF);
		if (StringUtils.isBlank(rech_conf)) {
			FrameUtil.throwBaseException1("系统参数异常");
		}
		Map<String, Object> paramMap = JSON.parseObject(rech_conf);
		if (paramMap == null) {
			FrameUtil.throwBaseException1("系统参数异常");
		}
		Map<String, Object> pcMap = (Map<String, Object>) paramMap.get("pc");
		if (pcMap == null) {
			FrameUtil.throwBaseException1("系统参数异常");
		}
		Map<String, Object> appMap = (Map<String, Object>) paramMap.get("app");
		if (appMap == null) {
			FrameUtil.throwBaseException1("系统参数异常");
		}
		Map<String, Object> iosMap = (Map<String, Object>) appMap.get("ios");
		Map<String, Object> androidMap = (Map<String, Object>) appMap
				.get("android");

		if (!pcMap.containsKey("authReturnUrl") || !pcMap.containsKey("pageUrl")
				|| !pcMap.containsKey("payUrl")
				|| !pcMap.containsKey("returnUrl") || !pcMap.containsKey("type")
				|| !pcMap.containsKey("user") || !iosMap.containsKey("user")
				|| !androidMap.containsKey("user")
				|| !appMap.containsKey("pageUrl")
				|| !appMap.containsKey("payUrl")
				|| !appMap.containsKey("type")) {
			FrameUtil.throwBaseException1("系统参数不完整");
		}
		//
		String rootUrl = FrameUtil.getConstResource("php.api.root");
		String pcRoot = FrameUtil
				.getConstResource("yjd_front.userRootPathHTTPS");
		String appRoot = FrameUtil.getConstResource("yjd_api.rootPath");

		String key = (String) pcMap.get("key");
		String appUser = (String) pcMap.get("user");
		String appType = (String) pcMap.get("type");
		String payUrl = (String) pcMap.get("payUrl");
		String pageUrl = pcRoot + (String) pcMap.get("pageUrl");
		String returnUrl = (String) pcMap.get("returnUrl");
		String authReturnUrl = (String) pcMap.get("authReturnUrl");

		// ios
		if (RechChannel.IOS.getCode() == rechargeOrder.getClient()) {
			key = (String) iosMap.get("key");
			appUser = (String) iosMap.get("user");
			appType = (String) appMap.get("type");
			payUrl = (String) appMap.get("payUrl");
			pageUrl = appRoot + (String) appMap.get("pageUrl");
		} else if (RechChannel.ANDROID.getCode() == rechargeOrder.getClient()) {// android
			key = (String) androidMap.get("key");
			appUser = (String) androidMap.get("user");
			appType = (String) appMap.get("type");
			payUrl = (String) appMap.get("payUrl");
			pageUrl = appRoot + (String) appMap.get("pageUrl");
		}

		if (StringUtils.isBlank(appUser) || StringUtils.isBlank(appType)
				|| StringUtils.isBlank(payUrl) || StringUtils.isBlank(key)
				|| StringUtils.isBlank(pageUrl)
				|| StringUtils.isBlank(authReturnUrl)
				|| StringUtils.isBlank(returnUrl)) {
			logger.info("appUser:" + appUser + ",appType:" + appType
					+ ",payUrl:" + key + ",pageUrl:" + pageUrl
					+ ",authReturnUrl:" + authReturnUrl + ",returnUrl:"
					+ returnUrl + ",client:" + rechargeOrder.getClient());
			logger.info("rech_conf:" + rech_conf + ",pcMap:" + JSON.toJSONString(pcMap));
			FrameUtil.throwBaseException1("配置异常");
		}

		QuickPayOrder quick = new QuickPayOrder();
		quick.setAppUser(appUser);
		quick.setAppType(appType);
		quick.setPayUrl(rootUrl + payUrl);
		quick.setReturnUrl(pageUrl);
		quick.setCallBackUrl(pcRoot + returnUrl);
		quick.setKey(key);
		// 如果是认证
		if (rechargeOrder.getAuthen()) {
			quick.setCallBackUrl(authReturnUrl);
		}
		return quick;
	}

	public static String getKey(String appUser) throws Exception {
		int client = RechChannel.PC.getCode();
		if (StringUtils.isNotBlank(appUser)) {
			if (!NumberUtils.isNumber(appUser)) {
				FrameUtil.throwBaseException1("app_user异常，无法解析请求");
			}
			int tp = Integer.valueOf(appUser);
			if (RechChannel.IOS.getCode() == tp) {
				client = RechChannel.IOS.getCode();
			} else if(RechChannel.ANDROID.getCode() == tp){
				client = RechChannel.ANDROID.getCode();
			}
		}
		RechargeOrderDto rechargeOrder = new RechargeOrderDto();
		rechargeOrder.setClient(client);
		return getInstance(rechargeOrder).getKey();
	}

}
